package org.go.scheduler.database;

import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.go.scheduler.database.util.StdJDBCConstants;
import org.go.trigger.Trigger;
import org.go.trigger.TriggerKey;
import org.go.util.Util;
import org.go.work.Work;

public class SimpleTriggerPersistenceDelegate implements TriggerPersistenceDelegate, StdJDBCConstants {

	protected String schedNameLiteral;
	protected String tablePrefix;

	@Override
	public boolean canHandleTriggerType(Trigger trigger) {
		return false;
		//((trigger instanceof RepeatTrigger) && !((RepeatTrigger) trigger).hasAdditionalProperties());
	}

	@Override
	public int deleteExtendedTriggerProperties(Connection conn, TriggerKey triggerKey) throws SQLException {
		PreparedStatement ps = null;

		try {
			ps = conn.prepareStatement(Util.rtp(DELETE_SIMPLE_TRIGGER, tablePrefix, schedNameLiteral));
			ps.setString(1, triggerKey.getName());
			ps.setString(2, triggerKey.getGroup());

			return ps.executeUpdate();
		} finally {
			Util.closeStatement(ps);
		}
	}

	@Override
	public String getHandledTriggerTypeDiscriminator() {
		return TTYPE_SIMPLE;
	}

	@SuppressWarnings("hiding")
	@Override
	public void initialize(String tablePrefix, String schedName) {
		this.tablePrefix = tablePrefix;
		this.schedNameLiteral = "'" + schedName + "'";
	}

	@Override
	public int insertExtendedTriggerProperties(Connection conn, Trigger trigger, String state, Work jobDetail) throws SQLException, IOException {

		//SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
		Trigger simpleTrigger = trigger;
		PreparedStatement ps = null;

		try {
			ps = conn.prepareStatement(Util.rtp(INSERT_SIMPLE_TRIGGER, tablePrefix, schedNameLiteral));
			ps.setString(1, trigger.getKey().getName());
			ps.setString(2, trigger.getKey().getGroup());
			ps.setInt(3, simpleTrigger.getRepeatCount());
			ps.setBigDecimal(4, new BigDecimal(String.valueOf(simpleTrigger.getRepeatInterval())));
			ps.setInt(5, simpleTrigger.getTimesTriggered());

			return ps.executeUpdate();
		} finally {
			Util.closeStatement(ps);
		}
	}

	@Override
	public TriggerPropertyBundle loadExtendedTriggerProperties(Connection conn, TriggerKey triggerKey) throws SQLException {

		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = conn.prepareStatement(Util.rtp(SELECT_SIMPLE_TRIGGER, tablePrefix, schedNameLiteral));
			ps.setString(1, triggerKey.getName());
			ps.setString(2, triggerKey.getGroup());
			rs = ps.executeQuery();

			if (rs.next()) {
				int repeatCount = rs.getInt(COL_REPEAT_COUNT);
				long repeatInterval = rs.getLong(COL_REPEAT_INTERVAL);
				int timesTriggered = rs.getInt(COL_TIMES_TRIGGERED);

				SimpleScheduleBuilder sb = SimpleScheduleBuilder.simpleSchedule().withRepeatCount(repeatCount).withIntervalInMilliseconds(repeatInterval);

				String[] statePropertyNames = { "timesTriggered" };
				Object[] statePropertyValues = { timesTriggered };

				return new TriggerPropertyBundle(sb, statePropertyNames, statePropertyValues);
			}

			throw new IllegalStateException("No record found for selection of Trigger with key: '" + triggerKey + "' and statement: " + Util.rtp(SELECT_SIMPLE_TRIGGER, tablePrefix, schedNameLiteral));
		} finally {
			Util.closeResultSet(rs);
			Util.closeStatement(ps);
		}
	}

	@Override
	public int updateExtendedTriggerProperties(Connection conn, Trigger trigger, String state, Work jobDetail) throws SQLException, IOException {
		//	Trigger simpleTrigger = (SimpleTrigger) trigger;
		Trigger simpleTrigger = trigger;
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(Util.rtp(UPDATE_SIMPLE_TRIGGER, tablePrefix, schedNameLiteral));
			ps.setInt(1, simpleTrigger.getRepeatCount());
			ps.setBigDecimal(2, new BigDecimal(String.valueOf(simpleTrigger.getRepeatInterval())));
			ps.setInt(3, simpleTrigger.getTimesTriggered());
			ps.setString(4, simpleTrigger.getKey().getName());
			ps.setString(5, simpleTrigger.getKey().getGroup());
			return ps.executeUpdate();
		} finally {
			Util.closeStatement(ps);
		}
	}
}
